package com.book.controller;


import com.book.model.config.Config;
import com.book.model.entity.*;
import com.book.model.repository.*;
import com.book.utils.utils.MD5Util;
import com.book.utils.utils.itext.PDFUtil;
import com.book.utils.utils.pinying.PinyingDuoYinziUtil;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 2018/4/2.
 */
@Api( value = "默认入口", description = "默认入口",tags="index")
@Controller("index_controller")
@RequestMapping("/api/index")
@CrossOrigin
public class IndexController extends BaseController {

    @Autowired
    OauthUrlRepository oauthUrlRepository;

    @Autowired
    OauthUserRepository oauthUserRepository;

    @Autowired
    TmpCacheRepository tmpCacheRepository;

    @Autowired
    UserRepository userRepository;

    @Autowired
    ArticleSectionsRepository articleSectionsRepository;

    @Autowired
    ArticleRepository articleRepository;

    @Autowired
    UserOauthSectionsRepository userOauthSectionsRepository;

    //PinyingDuoYinziUtil pinyingDuoYinziUtil;

    @GetMapping("/article/{id}/preview")
    public String goPageTest(@PathVariable("id")Long id,
                             HttpSession session,
                             HashMap<String, Object> map) throws FileNotFoundException {

        String token = null;
        User user = null;
        //已经登录进行验证登录情况
        token = (String)session.getAttribute("token");
        if(token != null && !token.equals("")){//有token,要对token的合法性进行检测
            String uid = tmpCacheService.get(token);
            if(uid == null){
                token = null;
            }else{
                user =  userRepository.findById(Long.parseLong(uid)).orElse(null);
                if(user == null || user.isDelete()){//非有效用户
                    token = null;
                }
            }
            if(token != null){
                tmpCacheService.delayedExpireTime(token,new Date().getTime()+1000*60*60*2);//延长有效期
            }
        }

        if(token == null || token.equals("")) {//未登录，进行登录授权
            String state = null;
            try {
                state = "article_preview_"+MD5Util.MD5Encode(""+id+System.currentTimeMillis()+Math.random());
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                map.put("msg","H5模式下，生成授权信息失败");
                return "error";
            }

            //String tmpCache = tmpCacheService.get("article_"+uuid);
            //if(tmpCache == null){
            tmpCacheService.set("article_"+id,state,1000*60*2);
            //}
            return "redirect:"+getPayjsOauthUrl(""+id,state);//跳转到授权页面
        }
        Article article = articleRepository.findById(id).orElse(null);
        if(article == null){
            map.put("msg","书籍不存在");
            return "error";
        }
        map.put("article",article);

        // 检测已经授权的章节
        List<UserOauthSections> userOauthSections = userOauthSectionsRepository.findAllByUserAndArticle(user,article);
        Map<Long,UserOauthSections> userOauthSectionsMap = new HashMap<>();
        if(userOauthSections != null && userOauthSections.size() > 0){
            for(UserOauthSections userOauthSection:userOauthSections){
                userOauthSectionsMap.put(userOauthSection.getId(),userOauthSection);
            }
        }
        List<ArticleSections> articleSections = articleSectionsRepository.findAllByArticle(article);
        int totalPage = 0;
        for(ArticleSections articleSection:articleSections){
            String content = org.apache.commons.text.StringEscapeUtils.unescapeHtml4(articleSection.getContent());
            articleSection.setContent(content);
            totalPage ++;
            articleSection.setStartPage(totalPage);
            if(articleSection.getType() == 2 && articleSection.getFile() != null) {
                articleSection.getFile().setUrl(Config.fileHost + "/api" + articleSection.getFile().getUrl());
            }
            if(userOauthSectionsMap.containsKey(articleSection.getId()) || articleSection.getPrice() == 0){//存在说明是购买过的或免费的
                articleSection.setFilePreViewPages(0);
            }
        }
        map.put("articleSections",articleSections);

        try {
            map.put("photo_url",Config.fileHost+"/api/common/download/pic/"+URLEncoder.encode(article.getPhoto().getName(),"utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //进入指定的页面
        return "article";
    }


    /**
     * 书籍详情页面
     * @param uuid
     * @param session
     * @param map
     * @return
     */
    @GetMapping("/article/{uuid}")
    public String goPage(@PathVariable("uuid")String uuid,
                         HttpSession session,
                         HashMap<String, Object> map) {

        OauthUrl oauthUrl = oauthUrlRepository.findOneByUuid(uuid);
        if(oauthUrl == null){
            //TODO 错误页面
            map.put("msg","书籍不存在");
            return "error";
        }
        String token = null;
        User user = null;
        //已经登录进行验证登录情况
        token = (String)session.getAttribute("token");
        if(token != null && !token.equals("")){//有token,要对token的合法性进行检测
            String uid = tmpCacheService.get(token);
            if(uid == null){
                token = null;
            }else{
                user =  userRepository.findById(Long.parseLong(uid)).orElse(null);
                if(user == null || user.isDelete()){//非有效用户
                    token = null;
                }
            }
            if(token != null){
                tmpCacheService.delayedExpireTime(token,new Date().getTime()+1000*60*60*2);//延长有效期
            }
        }

        if(token == null || token.equals("")) {//未登录，进行登录授权
            String state = null;
            try {
                state = "article_oauthurl_"+MD5Util.MD5Encode(uuid+System.currentTimeMillis()+Math.random());
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                map.put("msg","H5模式下，生成授权信息失败");
                return "error";
            }

            //String tmpCache = tmpCacheService.get("article_"+uuid);
            //if(tmpCache == null){
                tmpCacheService.set("article_"+uuid,state,1000*60*2);
            //}
            return "redirect:"+getPayjsOauthUrl(uuid,state);//跳转到授权页面
        }
        //检测是否为该用户可使用的文章地址
        boolean isOauth = false;
        User aUser = oauthUrl.getUser();
        if(aUser == null){//进行绑定
            oauthUrl.setUser(user);
            oauthUrl = oauthUrlRepository.saveAndFlush(oauthUrl);
            isOauth = true;
        }else if(aUser.getId() != user.getId()){
            map.put("msg","该链接已经失效");
            return "error";
        }

        Article article = oauthUrl.getArticle();
        map.put("article",article);

        List<ArticleSections> articleSections = articleSectionsRepository.findAllByArticle(article);
        int totalPage = 0;
        for(ArticleSections articleSection:articleSections){
            String content = org.apache.commons.text.StringEscapeUtils.unescapeHtml4(articleSection.getContent());
            articleSection.setContent(content);
            totalPage ++;
            articleSection.setStartPage(totalPage);
            if(articleSection.getType() == 2 && articleSection.getFile() != null) {
                articleSection.getFile().setUrl(Config.fileHost + "/api" + articleSection.getFile().getUrl());
            }
            articleSection.setFilePreViewPages(0);
            if(isOauth) {//记录授权章节
                UserOauthSections userOauthSections = new UserOauthSections();
                userOauthSections.setArticle(article);
                userOauthSections.setArticleSections(articleSection);
                userOauthSections.setUser(user);
                userOauthSectionsRepository.save(userOauthSections);
            }
        }
        map.put("articleSections",articleSections);


        try {
            map.put("photo_url",Config.fileHost + "/api/common/download/pic/"+URLEncoder.encode(article.getPhoto().getName(),"utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //进入指定的页面
        return "article";
    }

    public String getPayjsOauthUrl(String uuid,String state){
        String redirect_uri = Config.host + "/api/index/oauth_callback/"+uuid+"?state="+state;// 回调地址
        String url = null;
        try {
            url = "https://payjs.cn/api/openid?mchid="+Config.payjsMchId+"&callback_url="+ URLEncoder.encode(redirect_uri,"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return url;
    }


    @GetMapping("/sections/{sid}")
    public String goPage(
                         @PathVariable("sid")Long sid,
                         HttpSession session,
                         HashMap<String, Object> map) {
        User user = null;
        String token = (String)session.getAttribute("token");
        if(token != null && !token.equals("")){//有token,要对token的合法性进行检测
            String uid = tmpCacheService.get(token);
            if(uid == null){
                token = null;
            }else{
                user =  userRepository.findById(Long.parseLong(uid)).orElse(null);
                if(user == null || user.isDelete()){//非有效用户
                    token = null;
                }
            }
            if(token != null){
                tmpCacheService.delayedExpireTime(token,1000*60*60*2);//延长有效期
            }
        }
        if(token == null){
            map.put("msg","非法访问");
            return "error";
        }
        //检测是否有授权该书
        ArticleSections articleSections = articleSectionsRepository.findById(sid).orElse(null);
        Article article = articleSections.getArticle();
        OauthUrl oauthUrl = oauthUrlRepository.findOneByUserAndArticle(user,article);
        if(oauthUrl == null){
            map.put("msg","请先购买该电子书");
            return "error";
        }
        map.put("articleSections",articleSections);

        //进入指定的页面
        return "articleSections";
    }
    /**
     * payjs授权回调
     * @param uuid
     * @param openid
     * @param state
     * @param session
     * @param map
     * @return
     */
    @GetMapping("/oauth_callback/{uuid}")
    public String goPage(@PathVariable("uuid")String uuid,
                         @RequestParam(value = "openid",defaultValue = "")String openid,
                         @RequestParam(value = "state",defaultValue = "")String state,
                         HttpSession session,
                         HashMap<String, Object> map) {


        String tmpCache = tmpCacheService.get("article_"+uuid);
        if(tmpCache == null || !tmpCache.equals(state)){
            map.put("msg","非法授权");
            return "error";
        }
        User user = null;
        OauthUser oauthUser = oauthUserRepository.findOneByOpenid(openid);
        if(oauthUser == null){
            user = new User();
            user.setAccount(openid);
            user = userRepository.saveAndFlush(user);
            oauthUser = new OauthUser();
            oauthUser.setUser(user);
            oauthUser.setOpenid(openid);
            oauthUser.setUnionid(openid);
            oauthUser.setName("payjs(平台版)授权用户"+openid);
            oauthUser.setNickname("payjs(平台版)授权用户");
            oauthUser = oauthUserRepository.saveAndFlush(oauthUser);
            removeToken(user);
            saveToken("user",user,1);
        }else{
            user = oauthUser.getUser();
            removeToken(user);
            saveToken("user",user,1);
        }
        tmpCacheService.set(user.getAccessToken(),""+user.getId(),1000*60*60*2);
        session.setAttribute("token",user.getAccessToken());

        String url = null;
        if(state.startsWith("article_preview_")){
            url = Config.host + "/api/index/article/"+uuid+"/preview";// 回调地址;
        }else{
            url = Config.host + "/api/index/article/"+uuid;// 回调地址;
        }

        return "redirect:" + url;
    }
}
